//
//  BindDispose.swift
//  CSBind
//
//  Created by 万孟超 on 2023/12/23.
//

import Foundation

public class CSBindDispose {
    
    /// 是否忽略相同的值：如果即将改变的值和原来的值相同，则不联动
    public var isIgnoreSameValue = true {
        didSet {
            freshIgnoreSameValue()
        }
    }
    
    /// 绑定忽略次数
    public var bindIgnoreTimes: Int = 0 {
        didSet {
            updateIgnoreTimes()
        }
    }
    /// 绑定忽略次数和相同值绑定是否联动
    /// true：相同的值不消耗忽略次数
    /// false：不管值是否相同都消耗忽略次数
    public var bindIgnoreTimesByIgnoreValue: Bool = true {
        didSet {
            updateBindIgnoreTimesByIgnoreValue()
        }
    }
        
    /// 初始化
    public init() { }
    
    // MARK -- 键值都是KeyPath类型
    
    convenience public init<LT, RT, ValueType>(_ target: LT?, _ targetKeyPath: ReferenceWritableKeyPath<LT, ValueType>, _ binder: RT?, _ binderKeyPath: ReferenceWritableKeyPath<RT, ValueType>) where LT: NSObject, RT: NSObject, ValueType: Any {
        self.init()
        bind(target, targetKeyPath, binder, binderKeyPath)
    }
    // MARK -- 键值都是String类型
    
    convenience public init<LT, RT>(_ target: LT?, _ targetKeyPath: String, _ binder: RT?, _ binderKeyPath: String) where LT: NSObject, RT: NSObject {
        self.init()
        bind(target, targetKeyPath, binder, binderKeyPath)
    }
    // MARK -- 左边是String 右边是KeyPath
    
    convenience public init<LT, RT, ValueType>(_ target: LT?, _ targetKeyPath: String, _ binder: RT?, _ binderKeyPath: ReferenceWritableKeyPath<RT, ValueType>) where LT: NSObject, RT: NSObject, ValueType: Any {
        self.init()
        bind(target, targetKeyPath, binder, binderKeyPath)
    }
    // MARK -- 左边是KeyPath 右边是String
    
    convenience public init<LT, RT, ValueType>(_ target: LT?, _ targetKeyPath:  ReferenceWritableKeyPath<LT, ValueType>, _ binder: RT?, _ binderKeyPath: String) where LT: NSObject, RT: NSObject, ValueType: Any {
        self.init()
        bind(target, targetKeyPath, binder, binderKeyPath)
    }
    
    /// 绑定
    /// - Parameters:
    ///   - lBinder: 绑定者
    ///   - lBinderKeyPath: 绑定者的键值KeyPath
    ///   - rBinder: 绑定者
    ///   - rBinderKeyPath: 绑定者的键值KeyPath
    public func bind<LT, RT, ValueType>(_ lBinder: LT?, _ lBinderKeyPath: ReferenceWritableKeyPath<LT, ValueType>, _ rBinder: RT?, _ rBinderKeyPath: ReferenceWritableKeyPath<RT, ValueType>) where ValueType: Any, LT: NSObject, RT: NSObject { }
    
    /// 绑定
    /// - Parameters:
    ///   - lBinder: 绑定者
    ///   - lBinderKeyPath: 绑定者的键值KeyPath
    ///   - rBinder: 绑定者
    ///   - rBinderKeyPath: 绑定者的键值KeyPath
    public func bind<LT, RT>(_ lBinder: LT?, _ lBinderKeyPath: String, _ rBinder: RT?, _ rBinderKeyPath: String) where LT: NSObject, RT: NSObject { }
    
    /// 绑定
    /// - Parameters:
    ///   - lBinder: 绑定者
    ///   - lBinderKeyPath: 绑定者的键值KeyPath
    ///   - rBinder: 绑定者
    ///   - rBinderKeyPath: 绑定者的键KeyPathString
    public func bind<LT, RT, RV>(_ lBinder: LT?, _ lBinderKeyPath: String, _ rBinder: RT?, _ rBinderKeyPath: ReferenceWritableKeyPath<RT, RV>) where RV: Any, LT: NSObject, RT: NSObject { }
    
    /// 绑定
    /// - Parameters:
    ///   - lBinder: 绑定者
    ///   - lBinderKeyPath: 绑定者的键值KeyPath
    ///   - rBinder: 绑定者
    ///   - rBinderKeyPath: 绑定者的键值KeyPathString
    public func bind<LT, RT, LV>(_ lBinder: LT?, _ lBinderKeyPath: ReferenceWritableKeyPath<LT, LV>, _ rBinder: RT?, _ rBinderKeyPath: String) where LV: Any, LT: NSObject, RT: NSObject { }
    
    /// 取消绑定
    /// 取消绑定之后，只有重新绑定才会生效
    public func free() { }
    
    /// 暂停绑定
    /// 暂时停止绑定，和`run`可以配套使用
    public func pause() { }
    
    /// 启动绑定
    /// 绑定暂停后，调用此方法可以重新启动绑定
    public func run() { }
    
    /// 刷新是否忽略相同值
    /// 子类实现
    func freshIgnoreSameValue() { }
    
    /// 设置忽略次数
    func updateIgnoreTimes() { }
    
    /// 设置绑定忽略次数和相同值绑定是否联动
    func updateBindIgnoreTimesByIgnoreValue() { }
    
    /// 立即生效一次
    public func immediatelyAvaliable() { }
}
